package com.sg.framework.common.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;

import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import com.sg.framework.common.annotations.*;
import com.sg.framework.common.dto.*;
import com.sg.framework.common.redis.*;
import com.sg.framework.common.annotations.*;
import com.sg.framework.common.baseinfo.AuthContext;
import com.sg.framework.common.baseinfo.BaseInfoDO;
import com.sg.framework.common.baseinfo.BaseInfoHolder;
import com.sg.framework.common.dto.*;
import com.sg.framework.common.exception.BizException;
import com.sg.framework.common.mq.MsgInfo;
import com.sg.framework.common.redis.*;
import com.sg.framework.common.ro.OkrResult;
import lombok.Getter;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.skywalking.apm.toolkit.trace.CallableWrapper;

import java.io.*;
import java.lang.reflect.Field;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.io.Serial;
import java.util.Date;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.FutureTask;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static cn.hutool.core.util.CharUtil.UNDERLINE;


/**
 * @author ：CHS
 * @since 2022/2/16 14:11
 *
 *
 * @version 1.0
 */
public class CommonFunctionHelper {
    private static RedisUtil redisUtil;

    @lombok.Setter
    @Getter
    private static Map<String,String> configInfo = new HashMap<>();

    @Getter
    private static Map<String,Object> bizConfigInfo = new HashMap<>();

    private static String secStr;

    @Getter
    private static String filePath;

    private static final SnowflakeIdWorker uidGen = new SnowflakeIdWorker(2, 2);

    public static Map<String,String> tableInfo = new HashMap<>();

    public static String autoGen(String prefix) {
        return prefix + System.currentTimeMillis();
    }

    public static MsgInfo extractMsg(String msg) {
        return new MsgInfo();
    }

    public static void mergeObject(Object newObject, Object updateInfo) {
    }

    private static void setRedisUtil(RedisUtil data){
        redisUtil = data;
    }

    private static void setFilePath(String data){
        filePath = data;
    }

    private static void setSecStr(String data){
        secStr = data;
    }

    private static String getSecStr(){
        return secStr;
    }


    public static String humpToUnderline(String str) {
        String regex = "([A-Z])";
        Matcher matcher = Pattern.compile(regex).matcher(str);
        while (matcher.find()) {
            String target = matcher.group();
            str = str.replaceAll(target, "_" + target.toLowerCase());
        }
        return str;
    }

    public static void setBaseInfoToLocal(BaseInfoDO data) {
        AuthContext context = new AuthContext();
        context.setBaseInfo(data);
        BaseInfoHolder.contextHolder.set(context);
    }

    public static BaseInfoDO getBaseInfoFromLocal() {
        return BaseInfoHolder.contextHolder.get().getBaseInfo();
    }

    public static BaseInfoDO getBaseInfoFromCache() {
        return new BaseInfoDO();
    }

    public static void setBaseInfoToCache(BaseInfoDO data) {

    }

    public static Date getSpecTime() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
        return new Date(System.currentTimeMillis());
    }

    public static Page<?> startPage(int pageNum, int pageSize) {
        if (pageNum == 0 || pageNum < 0) {
            pageNum = 1;
        }
        if (pageSize == 0 || pageSize < 0) {
            pageSize = 1000;
        }
        return PageMethod.startPage(pageNum, pageSize);
    }

    public static void checkCode(String code) {
        if (code.equals("-1")) {
            throw new BizException("-1", false);
        }
    }


    private static Object getValue(Object obj, String targetField) {
        try {
            Field[] declaredFields = obj.getClass().getDeclaredFields();
            for (Field field : declaredFields) {
                if (field.getName().equals(targetField)) {
                    field.setAccessible(true);
                    return field.get(obj);
                }

            }
        } catch (Exception ignored) {

        }

        return null;
    }

    public static List<Map<String,String>> getDbData(String tableName,Map<String,String> filter) {


        String dbAddress = configInfo.get("security.db.address");
        String dbAccount = configInfo.get("security.db.account");
        String dbPassword = configInfo.get("security.db.password");

        Connection conn = null;
        Statement stmt = null;
        try {
//            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(dbAddress, dbAccount, dbPassword);
            stmt = conn.createStatement();

            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> entry : filter.entrySet()) {
                if (!sb.isEmpty()) {
                    sb.append(" AND ");
                }
                sb.append(entry.getKey()).append("=").append("'").append(entry.getValue()).append("'");
            }

            String sql = "SELECT * FROM " + tableName + " where " + sb;

            ResultSet rs = stmt.executeQuery(sql);
            List<Map<String,String>> result = new ArrayList<>();
            ResultSetMetaData metaData = rs.getMetaData();
            int columnCount = metaData.getColumnCount();

            while (rs.next()) {
                Map<String,String> row = new HashMap<>();
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = metaData.getColumnName(i);
                    String columnValue = rs.getString(i);
                    row.put(columnName, columnValue);
                }
                result.add(row);
            }
            return result;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {

            if(stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
        return new ArrayList<>();

    }

    public static JSONObject getLicenseData(String type){
        String data = getSecStr();
        if(data==null || data.isEmpty()){
            return null;
        }
        //data = "{\"branchName\":\"新数质测试\",\"info\":{\"111\":{\"applexName\":\"111\",\"authorizationEndTime\":\"111\",\"authorizationId\":\"777\",\"authorizationName\":\"新数质证书\",\"authorizationNum\":\"111\",\"authorizationObjectId\":\"111\",\"authorizationObjectType\":\"111\",\"authorizationSchemeId\":\"111\",\"authorizationSpaceId\":\"111\",\"authorizationStartTime\":\"111\",\"authorizationUnit\":\"111\",\"deployTypeCode\":\"111\",\"dnsAddresses\":\"111\",\"ipAddresses\":\"111\",\"isDeploymentEnabled\":\"111\",\"isMainAuthorization\":\"111\",\"schOpenRecordCode\":\"111\",\"schOpenRecordId\":\"111\",\"schemeAuthorizationType\":\"111\",\"serverMacCode\":\"111\",\"spaceShortName\":\"111\"},\"222\":{\"applexName\":\"222\",\"authorizationEndTime\":\"222\",\"authorizationId\":\"777\",\"authorizationName\":\"新数质证书\",\"authorizationNum\":\"222\",\"authorizationObjectId\":\"222\",\"authorizationObjectType\":\"222\",\"authorizationSchemeId\":\"222\",\"authorizationSpaceId\":\"222\",\"authorizationStartTime\":\"222\",\"authorizationUnit\":\"222\",\"deployTypeCode\":\"222\",\"dnsAddresses\":\"222\",\"ipAddresses\":\"222\",\"isDeploymentEnabled\":\"222\",\"isMainAuthorization\":\"222\",\"schOpenRecordCode\":\"222\",\"schOpenRecordId\":\"222\",\"schemeAuthorizationType\":\"222\",\"serverMacCode\":\"222\",\"spaceShortName\":\"222\"}}}";
        JSONObject jsonObject = JSONObject.parseObject(data);
        JSONObject infoObject = jsonObject.getJSONObject("info");
        return infoObject.getJSONObject(type);
    }

    public static String getIp(String netCardName,Integer ipNum){
        try {
            Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
            while(nets.hasMoreElements()){
                NetworkInterface one = nets.nextElement();
                if(one!=null && !one.getDisplayName().equals(netCardName)){
                    continue;
                }
                Enumeration<InetAddress> addressList = null;
                if (one != null) {
                    addressList = one.getInetAddresses();
                }
                int count = 0;
                if (addressList != null) {
                    while(addressList.hasMoreElements()){
                        count++;
                        InetAddress oneIp = addressList.nextElement();
                        System.out.println(one.getDisplayName() + ": ip "+ count + " is " +oneIp);
                        if(count==ipNum){
                          String ipStr = oneIp.toString();
                          if(ipStr.contains("/")){
                              ipStr = ipStr.replaceAll("/","");
                              System.out.println("ip has // , deal to "+ ipStr);
                          }
                          return ipStr;
                        }
                    }
                }
            }
        } catch (SocketException e) {
            System.out.println("getIp exception "+ Arrays.toString(e.getStackTrace()));
        }
        return "-1";
    }

    public static String getMac(String netCardName,String splitor){
        String retMac = "";
        try {
            Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
            while(nets.hasMoreElements()){
                NetworkInterface one = nets.nextElement();
                if(one!=null && !one.getDisplayName().equals(netCardName)){
                    continue;
                }
                byte [] mac = null;
                if (one != null) {
                    mac = one.getHardwareAddress();
                }
                if(mac!=null){
                    for (int i = 0; i < mac.length; i++) {
                        retMac = retMac + String.format("%02X%s", mac[i], (i < mac.length - 1) ? splitor : "");
                    }
                    System.out.println(one.getDisplayName() + ": mac is "+ retMac);
                    break;
                }
            }
        } catch (SocketException e) {
            System.out.println("getIp exception "+ Arrays.toString(e.getStackTrace()));
        }
        return retMac;
    }

    public static void delFile(String path){
        File file = new File(path);
        if (file.delete()) {
//            System.out.println("文件删除成功");
        } else {
//            System.out.println("文件删除失败");
        }
    }

    public static void writeFile(String path,String content){
        byte[] bytes = content.getBytes();
        Path openPath = Paths.get(path);
        try {
            Files.write(openPath, bytes, StandardOpenOption.APPEND);
//            System.out.println("文件创建成功并写入内容");
        } catch (IOException e) {
//            System.out.println("文件创建失败或写入内容失败");
//            e.printStackTrace();
        }
    }

    public static String getMD5Str(String str) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] digest = md5.digest(str.getBytes(StandardCharsets.UTF_8));

            // 将 byte[] 转换为 32 位十六进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : digest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');  // 补0，保证两位
                }
                hexString.append(hex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            // 可以记录日志或抛出运行时异常
            throw new RuntimeException("MD5 algorithm not found", e);
        }
    }

    public static String generateToken() {
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        return uuid;
    }

    public static void putUserBasicInfoToRedis(RedisUtil redisClient, UserBaseCacheInfoDto baseUserInfo) {
        BaseUserInfoForRedis retData = new BaseUserInfoForRedis();
        retData.setPowerCodeList(new ArrayList<PrivacyInfoForRedis>());
        retData.setRoleList(new ArrayList<RoleInfoForRedis>());
        BeanUtil.copyProperties(baseUserInfo, retData);
        if (baseUserInfo.getFrameworkPrivacyList() == null && baseUserInfo.getPowerAdminList() == null) {
            for (RoleCacheInfoDto role : baseUserInfo.getRoleList()) {
                RoleInfoForRedis roleData = new RoleInfoForRedis();
                BeanUtil.copyProperties(role, roleData);
                retData.getRoleList().add(roleData);
            }

            for (PrivacyCacheInfoDto code : baseUserInfo.getPowerCodeList()) {
                PrivacyInfoForRedis codeData = new PrivacyInfoForRedis();
                BeanUtil.copyProperties(code, codeData);
                retData.getPowerCodeList().add(codeData);
            }
            //无任何权限的普通员工场景
            Object jo = JSON.toJSON(retData);
            redisClient.set("登录令牌"+":"+"userbase-" + retData.getOriginalRoleMemberId(), jo.toString());
            return;
        } else if (baseUserInfo.getFrameworkPrivacyList() != null && baseUserInfo.getPowerAdminList() == null) {
            //有权限列表的普通员工场景
            for (PrivacyCacheInfoDto privacyInfo : baseUserInfo.getFrameworkPrivacyList()) {
                for (RoleInfoForRedis role : retData.getRoleList()) {
                    if (role.getRoleId() == privacyInfo.getAllocationObjectId()) {
                        if (role.getPowerCodeList() == null)
                            role.setPowerCodeList(new ArrayList<PrivacyInfoForRedis>());
                        PrivacyInfoForRedis privacyElm = new PrivacyInfoForRedis();
                        privacyElm.setPrivacyCode(privacyInfo.getPrivacyCode());
                        role.getPowerCodeList().add(privacyElm);
                    }
                }
            }
            Object jo = JSON.toJSON(retData);
            redisClient.set("登录令牌"+":"+"userbase-" + retData.getOriginalRoleMemberId(), jo.toString());
            return;
        } else if (baseUserInfo.getPowerAdminList() != null && baseUserInfo.getFrameworkPrivacyList() == null) {
            //有权限列表的管理员场景
            for (String code : baseUserInfo.getPowerAdminList()) {
                PrivacyInfoForRedis privacyElm = new PrivacyInfoForRedis();
                privacyElm.setPrivacyCode(code);
                retData.getPowerCodeList().add(privacyElm);
            }
            Object jo = JSON.toJSON(retData);
            redisClient.set("登录令牌"+":"+"userbase-" + retData.getOriginalRoleMemberId(), jo.toString());
            return;
        }
        throw new BizException("-1", "基础用户信息异常", false);
    }

    public static void putUserIrInfoToRedis(RedisUtil redisClient, UserIndCacheInfoDto indUserInfo) {
        UserIndInfoForRedis retData = new UserIndInfoForRedis();
        retData.setUserIndList(new ArrayList<UserIndElmInfoForRedis>());
        for (OrgCacheInfoDto oneElm : indUserInfo.getOrgInductionRecordList()) {
            UserIndElmInfoForRedis retElm = new UserIndElmInfoForRedis();
            BeanUtil.copyProperties(oneElm, retElm);
            if (retElm.getPowerCodeList() == null) retElm.setPowerCodeList(new ArrayList<PrivacyInfoForRedis>());

            //部门权限分配
            for (TributPowerDeptCacheInfoDto deptPrivacyElm : indUserInfo.getTributPowerDeptPositionList()) {
                if (deptPrivacyElm.getAllocationObjectId() == retElm.getOrganizationId()) {
                    PrivacyInfoForRedis privacyElm = new PrivacyInfoForRedis();
                    privacyElm.setPrivacyCode(deptPrivacyElm.getPrivacyCode());
                    retElm.getPowerCodeList().add(privacyElm);
                }
            }

            //职务权限分配
            for (TributPowerPositionCacheInfoDto positionPrivacyElm : indUserInfo.getTributPowerPositiontList()) {
                if (positionPrivacyElm.getAllocationObjectId() == retElm.getPositionId()) {
                    PrivacyInfoForRedis privacyElm = new PrivacyInfoForRedis();
                    privacyElm.setPrivacyCode(positionPrivacyElm.getPrivacyCode());
                    retElm.getPowerCodeList().add(privacyElm);
                }
            }

            //就职记录权限分配
            for (TributPowerInductionCacheInfoDto indPrivacyElm : indUserInfo.getTributPowerInductionRecordList()) {
                if (indPrivacyElm.getAllocationObjectId() == retElm.getPositionId()) {
                    PrivacyInfoForRedis privacyElm = new PrivacyInfoForRedis();
                    privacyElm.setPrivacyCode(indPrivacyElm.getPrivacyCode());
                    retElm.getPowerCodeList().add(privacyElm);
                }
            }

            //权限分配角色
            for (TributPowerRoleCacheInfoDto rolePrivacyElm : indUserInfo.getTributPowerRoleList()) {
                if (rolePrivacyElm.getPositionRoleCode() == retElm.getPositionRoleCode()) {
                    PrivacyInfoForRedis privacyElm = new PrivacyInfoForRedis();
                    privacyElm.setPrivacyCode(rolePrivacyElm.getPrivacyCode());
                    retElm.getPowerCodeList().add(privacyElm);
                }
            }

            retData.getUserIndList().add(retElm);
        }
    }

    public static void putPublicInfoToRedis(RedisUtil redisClient, PublicCacheInfoDto userInfo) {
        try {
            PublicInfoForRedis info = BeanUtil.toBean(userInfo, PublicInfoForRedis.class);
            Object jo = JSON.toJSON(info);
            redisClient.set("登录令牌:"+"token-" + info.getOriginalRoleMemberId(), userInfo.getToken());
            redisClient.set("登录令牌:"+ userInfo.getToken(), jo.toString());
        } catch (Exception ex) {
            System.out.println(ex);
        }

    }

    public static void putSpaceInfoToRedis(RedisUtil redisClient, SpaceInfoForRedis spaceInfo) {
        Object jo = JSON.toJSON(spaceInfo);
        redisClient.set("登录令牌"+":"+spaceInfo.getSpaceId(), jo.toString());
    }

    public static PublicCacheInfoDto getPublicInfoFromRedis(RedisUtil redisClient, String token) {
        String pubInfo = (String) redisClient.get("登录令牌:"+token);
        PublicCacheInfoDto retData = JSONObject.parseObject(pubInfo, PublicCacheInfoDto.class);
        return retData;
    }


    public static SpaceInfoForRedis getSpaceInfoFromRedis(RedisUtil redisClient, String spaceId) {
        String str = (String) redisClient.get("登录令牌"+":"+spaceId);
        SpaceInfoForRedis retData = JSONObject.parseObject(str, SpaceInfoForRedis.class);
        if (retData != null && retData.getOrgList() == null) {
            retData.setOrgList(new ArrayList<OrgInfoForRedis>());
        }
        return retData;
    }

    public static void changePublicInfoFromRedis(RedisUtil redisClient, String indId) {
        String token = (String) redisClient.get("登录令牌:"+"token-" + getBaseInfoFromLocal().getSpecOriginalRoleMemberId());
        PublicCacheInfoDto info = getPublicInfoFromRedis(redisClient, token);
        if (info == null) {
            return;
        }
        info.setInductionRecordId(indId);
        putPublicInfoToRedis(redisClient, info);
    }

    public static Boolean calculationMethod(Long lastLockoutTime, Long thresholdValue) {
        return lastLockoutTime >= thresholdValue;
    }

    public static void clearBaseInfo() {
        BaseInfoHolder.contextHolder.remove();
    }

    public static Date addDate(Date date, Integer dateNum) {
        Calendar rightNowDate = Calendar.getInstance();
        rightNowDate.setTime(date);
        rightNowDate.add(Calendar.YEAR, dateNum);//添加dateNum年 2023.10.31
        Date time = rightNowDate.getTime();
        return time;
    }

    public static Date getFutureTime() {
        Date retDate = null;
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            Date myDate = getCurrentTime();
            retDate = addDate(myDate, 100);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return retDate;
    }

    public static Date getCurrentTime() {
        return new Date();
    }

    public static String str2Md5(String inStr) {
        return inStr;
        /*
        char[] a = inStr.toCharArray();
        for (int i = 0; i < a.length; i++) {
            a[i] = (char) (a[i] ^ 't');
        }
        String s = new String(a);
        return s;

         */

    }

    public static String getUid() {
        return String.valueOf(uidGen.nextId());
    }


    public static String Md52Str(String inStr) {
        return str2Md5(str2Md5(inStr));

    }

    public static String getEquipMent() {
        return "PC";
    }

    public static String getSessionUrl() {
        return getBaseInfoFromLocal().getSpecLoginIp();
    }

    public static String getLogInIp() {
        return getBaseInfoFromLocal().getSpecUserLoginIp();
    }

    public static void asynExcute(Callable<String> call) {
        CallableWrapper wapper = new CallableWrapper(call);
        // 创建一个 FutureTask（doOneThing 任务）
        FutureTask<String> futureTask = new FutureTask<>(wapper);
        // 使用线程池执行 doOneThing 任务
        ForkJoinPool.commonPool().submit(futureTask);
    }

    public static Boolean checkCaptchaValid(VertifyReqDto req) {
        return true;
    }

    public static void clearTokenFromRedis(RedisUtil redisClient, String originalRoleMemberId) {
        String token = (String) redisClient.get("登录令牌:"+"token-" + originalRoleMemberId);
        if (token == null || token.isEmpty()) return;
        redisClient.delete("登录令牌:"+token);
        redisClient.delete("登录令牌:"+"token-" + originalRoleMemberId);
    }

    public static void clearSpaceInfoFromRedis(RedisUtil redisClient, SpaceInfoToRedisListReqDto req) {
        for (String spaceId : req.getSpaceInfoToRedisList()) {
            redisClient.delete(spaceId);
        }
    }

    public static void clearUserInfoFromRedis(RedisUtil redisClient, String originalRoleMemberId) {
        if (originalRoleMemberId == null || originalRoleMemberId.isEmpty()) return;
        redisClient.delete("登录令牌"+":"+"userbase-" + originalRoleMemberId);
        redisClient.delete("登录令牌"+":"+"inductionInfo-" + originalRoleMemberId);
    }

    public static void batchClearUserInfoFromRedis(RedisUtil redisClient, List<String> beginMemberList) {
        if (beginMemberList == null || beginMemberList.isEmpty()) return;
        for (String member : beginMemberList) {
            redisClient.delete("登录令牌"+":"+"userbase-" + member);
            redisClient.delete("登录令牌"+":"+"inductionInfo-" + member);
        }
    }

    public static void batchClearTokenFromRedis(RedisUtil redisClient, List<String> beginMemberList) {
        if (beginMemberList == null || beginMemberList.isEmpty()) return;
        for (String member : beginMemberList) {
            clearTokenFromRedis(redisClient, member);
        }
    }

    public static String firstChar(String srcData) {
        StringBuilder convert = new StringBuilder();
        if (StringUtils.isBlank(srcData)) {
            return "";
        }
        char word = srcData.charAt(0);
        String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
        if (pinyinArray != null) {
            convert.append(pinyinArray[0].charAt(0));
        } else {
            convert.append(word);
        }
        return convert.toString().toUpperCase();
    }

    public static Object extractResult(OkrResult<?> result) {
        if (!result.isSuccess()) {
            throw new BizException(result.getErrCode(), result.getMessage(), false);
        } else {
            return result.getData();
        }
    }

    public static String date2Str(Date date) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

        String dateString = formatter.format(date);
        return dateString;
    }

    public static String date2Str2(Date date) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String dateString = formatter.format(date);
        return dateString;
    }

    public static String getFilePath(String src) {
        if(src==null){
            return null;
        }
        if (src.startsWith("http")) return src;
        JSONObject configInfo = (JSONObject)redisUtil.get("平台软件配置" + ":" + "PLATFORM_OM_CONF");
        String path = configInfo.getString("fileDisplayRootPath");
        if (!src.startsWith("/")) src = "/" + src;
        if (path.endsWith("/")) {
            path = path.substring(0, path.lastIndexOf("/"));
        }
        return path + src;

    }



    public static String replaceFilePath(String src) {
        if(src==null){
            return null;
        }
        String configInfo = (String)redisUtil.get("平台软件配置" + ":" + "PLATFORM_OM_CONF");
        JSONObject configInfoJo = JSONObject.parseObject(configInfo);
        String path = configInfoJo.getString("fileDisplayRootPath");
        return src.replaceAll(path,"");
    }

    public static void main(String[] args) {
        String result = replaceFilePath("n/m/l");
        System.out.println(result);
    }
///----------------------------------------


    /**
     * 计算数据条数
     *
     * @param obj
     * @return
     */
    public static Integer getDataCount(Object obj) {
        if (obj == null) {
            return null;
        }
        int count = 1;
        List list = new ArrayList();
        if (obj instanceof List) {
            //for (Object o:(List)obj) {
            //list.add(o);
            list = (List) obj;
            return list.size();
        }


        return count;

    }


    /**
     * 获取初始标识
     *
     * @param sign:标识
     */
    public static String getInitCode(String sign) {
        if (sign != null) {
            return sign + "1000";
        }
        return null;
    }

    /**
     * 获取后续标识
     *
     * @param sign
     * @return
     */
    public static String getNextCode(List<String> sign) {
        if (sign.isEmpty() || sign == null) {
            return null;
        }
        String max = Collections.max(sign);
        Integer n = Integer.valueOf(max) + 1;
        String code = String.valueOf(n);
        return code;

    }


    /**
     * 周期类型排序规则
     *
     * @param startTime：开始时间
     * @param endTime：结束时间
     * @return
     */
    public static Integer getDateTimeOrderNum(Date startTime, Date endTime) {
        if (startTime != null && endTime != null) {
            long sTime = startTime.getTime();

            long eTime = endTime.getTime();

            Long result = eTime * 100 + (eTime - sTime);

            return result.intValue();
        }
        return null;
    }


    /**
     * 找N级标识
     *
     * @param code:当前数据的标识
     * @param cLevel:当前数据的层级
     * @param fLevel:指定的层级
     */
    public static String findLevelCode(String code, Long cLevel, Long fLevel) {
        if (code != null && cLevel != null && fLevel != null) {
            int a = cLevel.intValue();
            int b = fLevel.intValue();
            int c = (a - b) * 4;
            return code.substring(0, code.length() - c);
        }
        return null;
    }


    /**
     * 获取用户缓存角色列表
     *
     * @param token:token
     * @return
     */
    public static List getUserRoleListFromRedis(RedisUtil redisClient, String token) {
        if (redisClient != null && token != null) {
            PublicCacheInfoDto publicInfoFromRedis = getPublicInfoFromRedis(redisClient, token);
            String originalRoleMemberId = publicInfoFromRedis.getOriginalRoleMemberId();
            BaseUserInfoForRedis retData = getUserBasicInfoFromRedis(redisClient, originalRoleMemberId);
            List<RoleInfoForRedis> roleList = retData.getRoleList();
            return roleList;
        }
        return null;
    }

    /**
     * 获取用户全部权限
     *
     * @param redisClient
     * @param token
     * @return
     */
    public static List getUserAllPower(RedisUtil redisClient, String token) {
        if (redisClient != null && token != null) {
            PublicCacheInfoDto publicInfoFromRedis = getPublicInfoFromRedis(redisClient, token);
            String originalRoleMemberId = publicInfoFromRedis.getOriginalRoleMemberId();
            BaseUserInfoForRedis retData = getUserBasicInfoFromRedis(redisClient, originalRoleMemberId);
            List<RoleInfoForRedis> roleList = retData.getRoleList();
            List list = new ArrayList<>();
            List listCode = new ArrayList<>();
            for (int i = 0; i < roleList.size(); i++) {
                RoleInfoForRedis roleInfoForRedis = roleList.get(i);
                List<PrivacyInfoForRedis> powerCodeList = roleInfoForRedis.getPowerCodeList();
                for (PrivacyInfoForRedis privacyInfoForRedis : powerCodeList) {
                    if (!listCode.contains(privacyInfoForRedis.getPrivacyCode())) {
                        listCode.add(privacyInfoForRedis.getPrivacyCode());
                        list.add(privacyInfoForRedis);
                    }
                }
            }
            List<PrivacyInfoForRedis> powerCodeList = retData.getPowerCodeList();
            for (PrivacyInfoForRedis privacyInfoForRedis : powerCodeList) {
                if (!listCode.contains(privacyInfoForRedis.getPrivacyCode())) {
                    listCode.add(privacyInfoForRedis.getPrivacyCode());
                    list.add(privacyInfoForRedis);
                }
            }
            return list;
        }
        return null;
    }

    /**
     * 生成随机数
     *
     * @param n:几位数
     * @return
     */
    public static String generateRandomNum(Integer n) {
        if (n != 0) {
            String code = "";
            Random r = new Random();
            for (int i = 0; i < n; i++) {
                code += r.nextInt(10);
            }
            return code;
        }
        return null;
    }


    /**
     * 存缓存
     *
     * @param key
     * @param value
     */
    public static void putKvToRedis(String key, String value) {
        if (key != null && value != null) {
            RedisUtil redisUtil = new RedisUtil();
            redisUtil.set(key, value);
        }
    }

    /**
     * 列转行
     *
     * @param listData
     */
    public static List<Map<String, Object>> columnToRow(List<ColumnDto> listData) {
        String keyId = "id";
        if (listData == null) {
            return null;// new ArrayList<Map<String, Object>>();
        }
        List<String> listId = new ArrayList<String>();
        for (ColumnDto a : listData) {
            if (!listId.contains(a.getId())) {
                listId.add(a.getId());
            }
        }
        List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
        for (String id : listId) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put(keyId, id);
            for (ColumnDto a : listData) {
                if (a.getId().equals(id)) {
                    String key = a.getKey().toLowerCase();
                    int len = key.length();
                    StringBuilder sb = new StringBuilder(len);
                    for (int i = 0; i < len; i++) {
                        char c = key.charAt(i);
                        if (c == UNDERLINE) {
                            if (++i < len) {
                                sb.append(Character.toUpperCase(key.charAt(i)));
                            }
                        } else {
                            sb.append(c);
                        }
                    }
                    String k = sb.toString();
                    map.put(k, a.getValue());
                }

            }
            listMap.add(map);
        }
        return listMap;

    }

    /**
     * 列转行标识
     *
     * @param listData
     * @param keyId
     * @return
     */
    public static List<Map<String, Object>> columnToRow(List<Map> listData, String keyId) {
        if (listData == null) {
            return null;// new ArrayList<Map<String, Object>>();
        }
        List<String> listId = new ArrayList<String>();
        for (Map<String, Object> a : listData) {
            String id = a.get(keyId) == null ? null : a.get(keyId).toString();
            if (!listId.contains(id) && id != null) {
                listId.add(id);
            }
        }
        List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
        for (String id : listId) {
            Map<String, Object> map = new HashMap<String, Object>();
            //map.put(keyId,id);
            for (Map<String, Object> a : listData) {
                String idvalue = a.get(keyId) == null ? null : a.get(keyId).toString();
                if (idvalue.equals(id)) {
                    Set<String> keys = a.keySet();
                    for (String key : keys) {
                        map.put(key, a.get(key));
                    }
                }
            }
            listMap.add(map);
        }
        return listMap;
    }

    public static List<Map<String, Object>> COLUMN_TO_ROW_CODE(Object listData, String keyId) {
        String str = JSONObject.toJSONString(listData);
        List<Map> listMap = JSON.parseArray(str, Map.class);
        return columnToRow(listMap, keyId);
    }

    public static List<TreeNode> buildTree(List<Object> nodeList) {
        Map<String, TreeNode> newMap = new HashMap<>();
        List<TreeNode> result = new ArrayList<>();
        for (Object node : nodeList) {
            TreeNode treeNode = new TreeNode();
            treeNode.setSelf(node);
            newMap.put(getPriId(node), treeNode);
        }
        for (Object node : nodeList) {
            TreeNode parent = newMap.get(getParentId(node));
            if (ObjectUtil.isNotNull(parent)) {
                if (CollUtil.isEmpty(parent.getChildrenList())) {
                    List<TreeNode> ch = new ArrayList<>();
                    ch.add(newMap.get(getPriId(node)));
                    parent.setChildrenList(ch);
                } else {
                    List<TreeNode> ch = parent.getChildrenList();
                    ch.add(newMap.get(getPriId(node)));
                }
            } else {
                TreeNode fParent = newMap.get(getFid(node));
                if (ObjectUtil.isNotNull(fParent)) {
                    //子数据集的根节点
                    if (CollUtil.isEmpty(fParent.getChildrenList())) {
                        List<TreeNode> ch = new ArrayList<>();
                        ch.add(newMap.get(getPriId(node)));
                        fParent.setChildrenList(ch);
                    } else {
                        List<TreeNode> ch = fParent.getChildrenList();
                        ch.add(newMap.get(getPriId(node)));
                    }
                } else {
                    //为主数据集的根节点
                    result.add(newMap.get(getPriId(node)));
                }
            }
        }
        return result;
    }

    public static String getParentId(Object node) {
        try {
            Class classzz = node.getClass();
            Field[] declaredFields = classzz.getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                TreeType falg = field.getAnnotation(TreeType.class);
                if (falg.value().equals("pid")) {
                    return (String) field.get(node);
                }
            }
        } catch (Exception e) {

        }
        return "-1";
    }

    public static String getPriId(Object node) {
        try {
            Class classzz = node.getClass();
            Field[] declaredFields = classzz.getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                TreeType falg = field.getAnnotation(TreeType.class);
                if (falg.value().equals("id")) {
                    return (String) field.get(node);
                }
            }
        } catch (Exception e) {

        }
        return "-1";
    }

    public static String getFid(Object node) {
        try {
            Class classzz = node.getClass();
            Field[] declaredFields = classzz.getDeclaredFields();
            for (Field field : declaredFields) {
                field.setAccessible(true);
                TreeType falg = field.getAnnotation(TreeType.class);
                if (falg.value().equals("fid")) {
                    return (String) field.get(node);
                }
            }
        } catch (Exception e) {

        }
        return "-1";
    }

    public static BaseUserInfoForRedis getUserBasicInfoFromRedis(RedisUtil redisClient, String originalRoleMemberId) {
        String str = (String) redisClient.get("登录令牌"+":"+"userbase-" + originalRoleMemberId);
        if (str == null || str.isEmpty()) {
            return new BaseUserInfoForRedis();
        }
        BaseUserInfoForRealRedis redisData = JSONObject.parseObject(str, BaseUserInfoForRealRedis.class);
        BaseUserInfoForRedis retData = new BaseUserInfoForRedis();
        BeanUtil.copyProperties(redisData, retData, "birthday");
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        try {
            if (redisData.getBirthday() != null && !redisData.getBirthday().isEmpty()) {
                date = ft.parse(redisData.getBirthday());
                retData.setBirthday(date);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return retData;
    }

    public static UserIndInfoForRedis getUserIrInfoFromRedis(RedisUtil redisClient, String originalRoleMemberId) {
        String str = (String) redisClient.get("登录令牌"+":"+"inductionInfo-" + originalRoleMemberId);
        if (str == null || str.isEmpty()) {
            return new UserIndInfoForRedis();
        }
        UserIndInfoForRedis retData = JSONObject.parseObject(str, UserIndInfoForRedis.class);
        if (retData.getUserIndList() == null) {
            retData.setUserIndList(new ArrayList<>());
        }
        return retData;
    }

    public static void GenerateImage(String base64Str, String imgFilePath) {
        if (base64Str == null) // 图像数据为空
            return;
        try {
            // Base64解码
            byte[] bytes = Base64.getDecoder().decode(base64Str);
            for (int i = 0; i < bytes.length; ++i) {
                if (bytes[i] < 0) {// 调整异常数据
                    bytes[i] += 256;
                }
            }
            // 生成jpeg图片
            OutputStream out = new FileOutputStream(imgFilePath);
            out.write(bytes);
            out.flush();
            out.close();
            //====
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public static void buildQueryWrapperLike(QueryWrapper<?> queryWrapper, List<FieldInfo> likeList, Map<String, Object> fieldInfoMap) {
        for (FieldInfo columnInfo : likeList) {
            if (fieldInfoMap.get(columnInfo.getName()) != null) {
                if (columnInfo.getLikeType() == 2L) {
                    queryWrapper.likeRight(columnInfo.getName(), fieldInfoMap.get(columnInfo.getName()));
                } else {
                    queryWrapper.like(columnInfo.getName(), fieldInfoMap.get(columnInfo.getName()));
                }
            }
        }
    }

    public static void buildQueryWrapperEq(QueryWrapper<?> queryWrapper, Map<String, Object> fieldInfo, List<FieldInfo> likeFieldList) {
        Map<String, String> index = new HashMap<>();
        if (likeFieldList != null) {
            for (FieldInfo oneFile : likeFieldList) {
                index.put(oneFile.getName(), oneFile.getName());
            }
        }
        for (Map.Entry<String, Object> columnInfo : fieldInfo.entrySet()) {
            if (!index.containsKey(columnInfo.getKey())) {
                queryWrapper.eq(columnInfo.getKey(), columnInfo.getValue());
            }
        }
    }

    public static void buildQueryWrapperOrder(QueryWrapper<?> queryWrapper, List<FieldInfo> orderList) {
        for (FieldInfo orderColumn : orderList) {
            if (orderColumn.getOrderType() != null && orderColumn.getOrderType() == 1)
                queryWrapper.orderByAsc(orderColumn.getName());
            if (orderColumn.getOrderType() != null && orderColumn.getOrderType() == 2)
                queryWrapper.orderByDesc(orderColumn.getName());
        }
    }


    public static void buildTimeRange(QueryWrapper<?> queryWrapper, List<FieldInfo> orderList) {
        for (FieldInfo orderColumn : orderList) {
            if (orderColumn.getOrderType() != null && orderColumn.getOrderType() == 1)
                queryWrapper.orderByAsc(orderColumn.getName());
            if (orderColumn.getOrderType() != null && orderColumn.getOrderType() == 2)
                queryWrapper.orderByDesc(orderColumn.getName());
        }
    }

    public static String constructRedirectUrl(String casServerLoginUrl, String serviceParameterName, String serviceUrl, boolean renew, boolean gateway) {
        return casServerLoginUrl + (casServerLoginUrl.contains("?") ? "&" : "?") + serviceParameterName + "="
                + URLEncoder.encode(serviceUrl, StandardCharsets.UTF_8) + (renew ? "&renew=true" : "") + (gateway ? "&gateway=true" : "");
    }

    public static String constructRedirectUrl(String casServerLoginUrl, String serviceParameterName, String serviceUrl) {
        return casServerLoginUrl + (casServerLoginUrl.contains("?") ? "&" : "?") + serviceParameterName + "="
                + URLEncoder.encode(serviceUrl, StandardCharsets.UTF_8);
    }

    public static Map<String, Object> objectToMap(Object obj) throws Exception {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            Object value = field.get(obj);
            if (value != null && value instanceof String tmp) {
                if (tmp.isEmpty() || tmp.equals("---")) value = null;

            }
            if (value != null && !field.getName().equals("serialVersionUID")) {
                map.put(humpToUnderline(field.getName()), value);
            }
        }
        return map;
    }

    public static Map<String, Object> objectToMapForLamBda(Object obj) throws Exception {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            Object value = field.get(obj);
            if (value != null && value instanceof String tmp) {
                if (tmp.isEmpty() || tmp.equals("---")) value = null;
            }
            if (value != null && value instanceof List) {
                value = null;
            }
            if (value != null && !field.getName().equals("serialVersionUID")) {
                map.put(humpToUnderline(field.getName()), value);
            }
        }
        return map;
    }

    public static List<FieldInfo> getOrderList(Class classzz) throws Exception {
        List<FieldInfo> result = new ArrayList<>();
        Field[] declaredFields = classzz.getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            OrderFlag falg = field.getAnnotation(OrderFlag.class);
            FieldInfo fieldInfo = new FieldInfo();
            fieldInfo.setName(humpToUnderline(field.getName()));
            if (falg != null && falg.orderType().toLowerCase(Locale.ROOT).equals("asc")) fieldInfo.setOrderType(1L);
            if (falg != null && falg.orderType().toLowerCase(Locale.ROOT).equals("desc")) fieldInfo.setOrderType(2L);
            if (fieldInfo.getOrderType() != null) result.add(fieldInfo);
        }
        return result;
    }

    public static List<FieldInfo> getLikeFiled(Class classzz) throws Exception {
        List<FieldInfo> result = new ArrayList<>();
        Field[] declaredFields = classzz.getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            LikeFlag falg = field.getAnnotation(LikeFlag.class);
            FieldInfo fieldInfo = new FieldInfo();
            fieldInfo.setName(humpToUnderline(field.getName()));
            if (falg != null && falg.likeType().toLowerCase(Locale.ROOT).equals("like")) fieldInfo.setLikeType(1L);
            if (falg != null && falg.likeType().toLowerCase(Locale.ROOT).equals("right_like"))
                fieldInfo.setLikeType(2L);
            if (fieldInfo.getLikeType() != null) result.add(fieldInfo);
        }
        return result;
    }

    public static List<FieldInfo> getRangeField(Class classzz) throws Exception {
        List<FieldInfo> result = new ArrayList<>();
        Field[] declaredFields = classzz.getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            RangeType falg = field.getAnnotation(RangeType.class);
            FieldInfo fieldInfo = new FieldInfo();
            fieldInfo.setName(humpToUnderline(field.getName()));
            if (falg != null && falg.RangeType().toLowerCase(Locale.ROOT).equals(">=")) {
                fieldInfo.setRangeType(1L);
            }

            if (falg != null && falg.RangeType().toLowerCase(Locale.ROOT).equals(">")) {
                fieldInfo.setRangeType(2L);
            }

            if (falg != null && falg.RangeType().toLowerCase(Locale.ROOT).equals("<=")) {
                fieldInfo.setRangeType(3L);
            }

            if (falg != null && falg.RangeType().toLowerCase(Locale.ROOT).equals("<")) {
                fieldInfo.setRangeType(4L);
            }

            if (fieldInfo.getLikeType() != null) {
                result.add(fieldInfo);
            }
        }
        return result;
    }

    public static void buildQueryWrapperCompare(QueryWrapper<?> queryWrapper, List<FieldInfo> compareFiledList, Map<String, Object> fieldInfo) {
        for (FieldInfo compareFile : compareFiledList) {
            if (compareFile.getRangeType() != null && compareFile.getRangeType() == 1) {
                if (fieldInfo.get(compareFile.getName()) != null) {
                    queryWrapper.ge(compareFile.getName(), fieldInfo.get(compareFile.getName()));
                }
            }
            if (compareFile.getRangeType() != null && compareFile.getRangeType() == 2) {
                if (fieldInfo.get(compareFile.getName()) != null) {
                    queryWrapper.gt(compareFile.getName(), fieldInfo.get(compareFile.getName()));
                }
            }
            if (compareFile.getRangeType() != null && compareFile.getRangeType() == 3) {
                if (fieldInfo.get(compareFile.getName()) != null) {
                    queryWrapper.le(compareFile.getName(), fieldInfo.get(compareFile.getName()));
                }
            }
            if (compareFile.getRangeType() != null && compareFile.getRangeType() == 4) {
                if (fieldInfo.get(compareFile.getName()) != null) {
                    queryWrapper.lt(compareFile.getName(), fieldInfo.get(compareFile.getName()));
                }
            }
        }
    }

    public static void nbDbWorker(Connection conn, Object param, String cmd, String extInfo) {
        NbDbWoker worker = new NbDbWoker();
        switch (cmd) {
            case "updateSortNumCom":
                worker.updateSortNumCom(conn, param);
                break;
            case "releaseSingleDataCom":
                worker.releaseSingleDataCom(conn, param);
                break;
            case "archiveBatchSingleDataCom":
                worker.archiveBatchSingleDataCom(conn, param);
                break;
            case "archiveSingleDataCom":
                worker.archiveSingleDataCom(conn, param);
                break;
            case "deleteSingleDataCom":
                worker.deleteSingleDataCom(conn, param);
                break;
            case "undoArchiveBatchSingleDataCom":
                worker.undoArchiveBatchSingleDataCom(conn, param);
                break;
            case "reviseNotBatchContent":
                worker.reviseNotBatchContent(conn, param);
                break;
            case "undoReviseBatchSingleData":
                worker.undoReviseBatchSingleData(conn, param);
                break;
            case "ADD_NUMERICAL":
                worker.automicAdd(conn, param, extInfo);
                break;
            case "SUBTRACT_NUMERICAL":
                worker.automicsub(conn, param, extInfo);
                break;
        }
    }

    /**
     * 下划线转驼峰
     *
     * @param str 目标字符串
     * @return: java.lang.String
     */
    public static String underlineToHump(String str) {
        str = str.toLowerCase(Locale.ROOT);
        String regex = "_(.)";
        Matcher matcher = Pattern.compile(regex).matcher(str);
        while (matcher.find()) {
            String target = matcher.group(1);
            str = str.replaceAll("_" + target, target.toUpperCase());
        }
        return str;
    }

    public static void flushTableInfo(Set<Class<?>> classes){
        for(Class<?> oneClass : classes){
            TableName tableMask = oneClass.getAnnotation(TableName.class);
            RealTableName realTableName = oneClass.getAnnotation(RealTableName.class);
            if(tableMask!=null && realTableName!=null){
                tableInfo.put(realTableName.realTableName(),tableMask.value());
            }
        }
    }


    /**
     * 根据包名获取包下面所有的类名
     *
     * @param pack
     * @return
     * @throws Exception
     */
    public static Set<Class<?>> getClasses(String pack) throws Exception {
        // 第一个class类的集合
        Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
        // 是否循环迭代
        boolean recursive = true;
        // 获取包的名字 并进行替换
        String packageName = pack;
        String packageDirName = packageName.replace('.', '/');
        // 定义一个枚举的集合 并进行循环来处理这个目录下的things
        Enumeration<URL> dirs;
        try {
            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
            // 循环迭代下去
            while (dirs.hasMoreElements()) {
                // 获取下一个元素
                URL url = dirs.nextElement();
                // 得到协议的名称
                String protocol = url.getProtocol();
                // 如果是以文件的形式保存在服务器上
                if ("file".equals(protocol)) {
                    // 获取包的物理路径
                    String filePath = URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8);
                    // 以文件的方式扫描整个包下的文件 并添加到集合中
                    findClassesInPackageByFile(packageName, url.getFile(), recursive, classes);
                } else if ("jar".equals(protocol)) {
                    // 如果是jar包文件
                    // 定义一个JarFile
                    System.out.println("jar类型的扫描");
                    JarFile jar;
                    try {
                        // 获取jar
                        jar = ((JarURLConnection) url.openConnection()).getJarFile();
                        // 从此jar包 得到一个枚举类
                        Enumeration<JarEntry> entries = jar.entries();
                        findClassesInPackageByJar(packageName, entries, packageDirName, recursive, classes);
                    } catch (IOException e) {
                        // log.error("在扫描用户定义视图时从jar包获取文件出错");
                        e.printStackTrace();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        flushTableInfo(classes);
        return classes;
    }

    /**
     * 以文件的形式来获取包下的所有Class
     *
     * @param packageName
     * @param packagePath
     * @param recursive
     * @param classes
     */
    private static void findClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, Set<Class<?>> classes) {
        // 获取此包的目录 建立一个File
        File dir = new File(packagePath);
        // 如果不存在或者 也不是目录就直接返回
        if (!dir.exists() || !dir.isDirectory()) {
            // log.warn("用户定义包名 " + packageName + " 下没有任何文件");
            return;
        }
        // 如果存在 就获取包下的所有文件 包括目录
        File[] dirfiles = dir.listFiles(new FileFilter() {
            // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
            @Override
            public boolean accept(File file) {
                return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
            }
        });
        // 循环所有文件
        for (File file : dirfiles) {
            // 如果是目录 则继续扫描
            if (file.isDirectory()) {
                findClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes);
            } else {
                // 如果是java类文件 去掉后面的.class 只留下类名
                String className = file.getName().substring(0, file.getName().length() - 6);
                try {
                    // 添加到集合中去
                    // classes.add(Class.forName(packageName + '.' +
                    // className));
                    // 经过回复同学的提醒，这里用forName有一些不好，会触发static方法，没有使用classLoader的load干净
                    classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));
                } catch (ClassNotFoundException e) {
                    // log.error("添加用户自定义视图类错误 找不到此类的.class文件");
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 以jar的形式来获取包下的所有Class
     *
     * @param packageName
     * @param entries
     * @param packageDirName
     * @param recursive
     * @param classes
     */
    private static void findClassesInPackageByJar(String packageName, Enumeration<JarEntry> entries, String packageDirName, final boolean recursive, Set<Class<?>> classes) {
        // 同样的进行循环迭代
        while (entries.hasMoreElements()) {
            // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
            JarEntry entry = entries.nextElement();
            String name = entry.getName();
            // 如果是以/开头的
            if (name.charAt(0) == '/') {
                // 获取后面的字符串
                name = name.substring(1);
            }
            // 如果前半部分和定义的包名相同
            if (name.startsWith(packageDirName)) {
                int idx = name.lastIndexOf('/');
                // 如果以"/"结尾 是一个包
                if (idx != -1) {
                    // 获取包名 把"/"替换成"."
                    packageName = name.substring(0, idx).replace('/', '.');
                }
                // 如果可以迭代下去 并且是一个包
                if ((idx != -1) || recursive) {
                    // 如果是一个.class文件 而且不是目录
                    if (name.endsWith(".class") && !entry.isDirectory()) {
                        // 去掉后面的".class" 获取真正的类名
                        String className = name.substring(packageName.length() + 1, name.length() - 6);
                        try {
                            // 添加到classes
                            classes.add(Class.forName(packageName + '.' + className));
                        } catch (ClassNotFoundException e) {
                            // .error("添加用户自定义视图类错误 找不到此类的.class文件");
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }


    public static void setBizConfigInfo(Map<String, Object> bizConfigInfo) {
        bizConfigInfo = bizConfigInfo;
    }

}
